package top.vanchor.myblog2back.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import top.vanchor.myblog2back.entity.BlogComment;
import top.vanchor.myblog2back.mapper.BlogCommentMapper;
import top.vanchor.myblog2back.service.IBlogCommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Ding
 * @since 2021-11-12
 */
@Service
public class BlogCommentServiceImpl extends ServiceImpl<BlogCommentMapper, BlogComment> implements IBlogCommentService {

    @Resource
    BlogCommentMapper blogCommentMapper;

    @Override
    public List<BlogComment> getCommentTreeByBlogId(int blogId,Integer uId) {
        //获取树状评论byBlogId
        List<BlogComment> commentsDemo = blogCommentMapper.getAllCommentsByBlogId(blogId,uId);
        //将树状结构的三级以下赋予（显示A 回复 B这样的条件）
        List<BlogComment> demo = findParent(commentsDemo);
        //按时间顺序排序
        List<BlogComment> format = toFormat(demo);
        return format;
    }

    @Override
    public int toPublishComment(BlogComment blogComment) {
        return blogCommentMapper.insert(blogComment);
    }

    @Override
    public int getCommentNumByBlogId(Integer blogId) {
        QueryWrapper<BlogComment> wrapper = new QueryWrapper<>();
        wrapper.eq("comment_blog_id", blogId);
        return blogCommentMapper.selectCount(wrapper);
    }

    @Override
    public int toDelCommentById(int comment_id) {
        //获取所有子节点id
        List<Integer> allIDs = blogCommentMapper.getDelIdsIgnoreThisId(comment_id);
        //把本体也添加进去
        allIDs.add(comment_id);
        //再联系库，把这些ID删除，并返回删除数量
        return blogCommentMapper.toDelCommentByIds(allIDs);
    }

    @Override
    public int toLikeComment(int commentId, int uId, int type) {
        return blogCommentMapper.toLikeComment(commentId,uId,type);
    }

    private List<BlogComment> toFormat(List<BlogComment> demo) {
        //一级封装
        List<BlogComment> firstList = demo;
//        for (int i = 0; i < demo.size(); i++) {
//            firstList.add(demo.get(demo.size()-1-i));
//        }
        //二级封装
        List<BlogComment> secondList = new ArrayList<>();
        for (int i = 0; i < firstList.size(); i++) {
            BlogComment comment = firstList.get(i);
            List<BlogComment> comments = new ArrayList<>();
            for (int j = 0; j < firstList.get(i).getComments().size(); j++) {
                comments.add(firstList.get(i).getComments().get(firstList.get(i).getComments().size() - 1 - j));
            }
            comment.setComments(comments);
            secondList.add(comment);
        }
        return secondList;
    }

    public List<BlogComment> findParent(List<BlogComment> comments) {
        //修改--需要显示回复....
        if (!comments.isEmpty()){
            for (BlogComment blogComment : comments) {
                blogComment.setNeedShow(false);
                if (!blogComment.getComments().isEmpty()){
                    for (BlogComment blogComment1:blogComment.getComments()){
                        blogComment1.setNeedShow(false);
                    }
                }
            }
        }

        for (BlogComment comment : comments) {

            // 防止checkForComodification(),而建立一个新集合
            ArrayList<BlogComment> fatherChildren = new ArrayList<>();

            // 递归处理子级的回复，即回复内有回复
            findChildren(comment, fatherChildren);

            // 将递归处理后的集合放回父级的孩子中
            comment.setComments(fatherChildren);
        }
        return comments;
    }

    public void findChildren(BlogComment parent, List<BlogComment> fatherChildren) {

        // 找出直接子级
        List<BlogComment> comments = parent.getComments();

        // 遍历直接子级的子级
        for (BlogComment comment : comments) {

            // 若非空，则还有子级，递归
            if (!comment.getComments().isEmpty()) {
                findChildren(comment, fatherChildren);
            }

            // 已经到了最底层的嵌套关系，将该回复放入新建立的集合
            fatherChildren.add(comment);

            // 容易忽略的地方：将相对底层的子级放入新建立的集合之后
            // 则表示解除了嵌套关系，对应的其父级的子级应该设为空
            comment.setComments(new ArrayList<>());
        }
    }
}
